﻿/********************************************************************
	created:	2015/08/07
	created:	7:8:2015   10:29
	filename: 	LaserAutoCode.h
	author:		luhuibing
	
	purpose:	实现组合跳码类
*********************************************************************/
#pragma once

#include <time.h>
#include <vector>
using namespace std;


#define			_MAX_STRING				_T("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")

enum AUTO_TYPE
{
	AUTO_UNDEF				= -1,			// 未定义
	AUTO_FIXED,								// 固定码
	AUTO_SERIALNUM,							// 序列号
	AUTO_DATE,								// 日期
	AUTO_TIME,								// 时间
	AUTO_FILE,								// 文件
	AUTO_PANEL_NO,							// Panel号
	AUTO_PCS_NO,							// Pcs号
	AUTO_COUNT,								// 总数
};

struct tagPeriodTime
{
	CTime _BeginTime;
	CTime _EndTime;
	CString _strContent;
};

class CAutoCode
{
public:
	CAutoCode(void);
	CAutoCode(LPCTSTR);
	~CAutoCode(void);

	enum MODE_SN
	{
		MODE_SN_UNDEFINE		= -1,	// 未定义
		MODE_SN_DEC,					// 十进制
		MODE_SN_HEX_UPPER,				// 十六进制(大写)
		MODE_SN_HEX_LOWER,				// 十六进制(小写)
		MODE_SN_USER_DEFINE,			// 自定义
	};

	enum MODE_DATE
	{
		MODE_DATE_UNDEFINE		= -1,	// 未定义
		MODE_DATE_YEAR_W,
		MODE_DATE_YEAR_A,
		MODE_DATE_MOUNTH,
		MODE_DATE_DAY,
		MODE_DATE_DAY_OF_YEAR,
		MODE_DATE_DAY_OF_WEEK,
		MODE_DATE_WEEK_OF_YEAR,
		MODE_DATE_YEAR_1,
	};

	enum MODE_TIME
	{
		MODE_TIME_UNDEFINE		= -1,
		MODE_TIME_HOUR_W,
		MODE_TIME_HOUR_A,
		MODE_TIME_MINUTES,
		MODE_TIME_SECONDS,
		MODE_TIME_MILLISECONDS,
		MODE_TIME_PERIOD,
	};

	AUTO_TYPE GetType();
	void SetType(int nType){ m_nType = (AUTO_TYPE)nType; };
	CString GetCurrentDate(int dt);

	CString GetSNTemplateString()
	{ 
		return m_strSNTemplate[m_nModeSN]; 
	};
	CString GetSNTemplateString(int _nModeSN)
	{
		return m_strSNTemplate[m_nModeSN];
	};

	// 测试模式
	void DemoModle(bool bEnable = false){ m_bDemoMode = bEnable; };
	// 获取当前跳码
	CString GetAutoCode(BOOL bPanel = FALSE);
	// 跳码跳变
	bool NextAutoCode();
	// 设置固定码
	bool SetFixedAutoCode(CString str);
	// 获取固定码
	bool GetFixAutoCode(CString &str);
	// 序列号重置
	void ResetSN();
	// 判断SN是否复位
	bool SNIsReset(){ return (bool)m_bResetByDay; };
	// 设置SN复位
	void SetSNSeset(bool bSNReset = true);
	// 序列号初始化
	void SetSNAutoCode(CString strBeginSN, CString strCurrSN, CString strMaxSN, UINT nStepSN=1, UINT nMarkCount=1,\
		UINT nCurrMarkCount=0, UINT nModeSN=MODE_SN_DEC, CString strUserDefineTemplate=_T(""));
	// 获取序列号参数
	bool GetSNAutoCode(CString &strBeginSN, CString &strCurrSN, CString &strMaxSN, UINT &nStepSN, UINT &nMarkCount,\
		UINT &nCurrMarkCount, UINT &nModeSN, CString &strUserDefineTemplate);
	// 日期初始化
	void SetDateAutoCode(UINT nModeDate=MODE_DATE_YEAR_W, CStringArray *str = NULL);
	void SetDateAutoCode(UINT nModeDate = MODE_DATE_YEAR_W, CString strTemp = _T(""));
	bool GetDateAutoCode(UINT &nModeDate);
	// 时间初始化
	void SetTimeAutoCode(UINT nModeTime=MODE_TIME_HOUR_W);
	bool GetTimeAutoCode(UINT &nModeTime);
	// 文件初始化
	void SetFileAutoCode(CString strFile);
	bool GetFileAutoCode(CString &strFile);
	// 清除所有数据
	void Clear();
	// 设置模板变量
	void SetDateTemplateString(CString strTemp);
	// 获取当前年月日信息
	CString GetCurrentDayString();
private:
	AUTO_TYPE m_nType;
	CString m_strCode;

	bool m_bDemoMode;
	// 固定码

	// 序列号
	CString m_strBeginSN;				// 开始序号
	CString m_strCurrentSN;				// 当前序号
	CString m_strMaxSN;					// 最大序号
	UINT m_nStepSN;						// 序号增量
	UINT m_nMarkCount;					// 每个标刻次数
	UINT m_nCurMarkCount;				// 当前标刻次数
	int m_nPicsCount;

	UINT m_nModeSN;						// 序列号模式
	bool m_bUserDefine;					// 是否可以使用UserDefine
	CString m_strSNTemplate[4];			// 序列号模板
	bool m_bResetByDay;					// 按天复位
	CString m_strCurrentDay;			// 当前年月日

	bool NextSN();						// 下一个序列号
	
	// 日期
	CString m_strDateTemplate[MAX_PATH];// 日期模板数据
	UINT GetSize(CString[]);			// 获取数据模板大小
	void ClearData(CString[]);			// 清空数据
//	CStringArray m_strDateTemplate;		// 日期模板数据
	UINT m_nModeDate;					// 日期模板Index
	bool NextDate();					// 下一个日期数据

	// 时间
	UINT m_nModeTime;					// 时间模板Index
	bool NextTime();					// 下一个时间数据

	// 时间段
	vector<tagPeriodTime> m_vPeriodTime;// 时间段模板
	bool NextPeriodTime();				// 下一个时间段数据

	// 文件
	CString m_strFilePath;
	bool NextFileCode();
};

class CLaserAutoCode
{
public:
	CLaserAutoCode(void);
	~CLaserAutoCode(void);

	void Add(CAutoCode autocode);
	void Add(LPCTSTR lpstr);

	bool HasePanelCode();
	void DemoMode(bool bEnable = false){ m_bDemoModle = bEnable; };
	bool MoveNext(UINT nIndex);			// 下标nIndex元素后移1位
	bool MovePrev(UINT nIndex);			// 下标nIndex元素前移1位
	bool DeleteIndex(UINT nIndex);		// 删除下标nIndex元素
	CString GetLaserCode(BOOL bPanel = FALSE);				// 获取当前组合类值
	bool GetNextLaserCode();			
	CString GetAt(int pos);

	void Clear()
	{
		m_vAutoCode.clear();
		vector<CAutoCode>().swap(m_vAutoCode);
	};
	CAutoCode* at(int pos);
	int Size();
	
	CString m_strName;					// 别名
private:
	vector<CAutoCode> m_vAutoCode;
	bool m_bDemoModle;
};

class CRandomStr
{
public:
	CRandomStr(void);
	CRandomStr(CString);
	~CRandomStr(void);
	void SetRandomTemplate(CString);
	CString GetRandomString(int nSize=1);
private:
	CString m_strdata;
};

